/*
This software is distributed under the Simplified BSD License:

Copyright (c) 2008, Chris Venter <chris.venter@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, 
    	this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, 
    	this list of conditions and the following disclaimer in the documentation 
    	and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
DAMAGE.
*/
#ifndef GENERIK_GLADE_H
#define GENERIK_GLADE_H

/** \file glade.h
Defines an encapsulation of the glade interface to make it a little easier and cleaner
to use (not that it is not already!).
The encapsulation also derives from the generik::gtk::widget class, which itself
is a wrapper around the obiquous GtkWidget.
*/

#include <generik/gtk.h>
#include <glade/glade.h>

#include <string>

#include "gtk.h"
#include "tracing.h"

/** \def GENERIK_SIGNAL_CONNECT_WIDGET
A macro which connects a widget to a similiarly named callback on the "clicked" signal.
It is useful when a whole bunch of connections have to be made in a row.
*/
#define GENERIK_SIGNAL_CONNECT_WIDGET(NAME) \
	g_signal_connect(G_OBJECT(get_widget(#NAME)), "clicked", G_CALLBACK(on_##NAME), this)

namespace generik
{
	
	namespace glade
	{
	
		/** An encapsulation of a GladeXML instance, derived from gtkwidget.
		This makes loading, instancing and using a GladeXML object easy, and provides access methods to interact
		smoothly with the instance. Since a gui may contain children, extra methods which
		interact the possible children are provided.
		*/
		struct xml
		: gtk::widget
		{
			GladeXML* _xml;
		
			/** Constructor which builds a gui from an xml file.
			*/
			xml(const std::string& xml_file)
			{
				GENERIK_TRACER;
				GENERIK_GDK_ENTER;
				_xml = glade_xml_new(xml_file.c_str(), NULL, NULL);
				GtkWidget* root = glade_xml_get_widget(_xml, "root");
				set_widget(root);
			}
			/** Constructor which builds a gui from a named widget inside an xml file.
			*/
			xml(const std::string& xml_file, const std::string& widget_in)
			{
				GENERIK_TRACER;
				GENERIK_GDK_ENTER;
				_xml = glade_xml_new(xml_file.c_str(), widget_in.c_str(), NULL);
				GtkWidget* root = glade_xml_get_widget(_xml, widget_in.c_str());
				set_widget(root);
			}
			~xml()
			{
				GENERIK_TRACER;
				// the following causes a *** glibc detected *** ./<executable>: free(): invalid pointer: 0x08062990 ***
				// if the xml object has been destroyed before. Does this mean we do not need to do reference counting?
				// is the memory free'd by itself?
				// g_free(xml); //
			}
			
			void set_fullscreen()
			{
				GdkWindow* gdkwindow = gtk_widget_get_parent_window(get_widget());
				gdk_window_fullscreen(gdkwindow);
			}
			void set_nodecor()
			{
				GtkWidget* window = get_widget("window1");
				gtk_window_set_decorated(GTK_WINDOW(window), false);
			}
			
			using gtk::widget::get_widget;
		
			/** Returns a named child widget from the gui structure contained in the GladeXML instance.
			*/
			virtual GtkWidget* get_widget(const std::string& name_in)
			{
				GENERIK_GDK_ENTER;
				if (name_in.empty())
					return get_widget();
				else
					return glade_xml_get_widget(_xml, name_in.c_str());
			}
			
			using gtk::widget::set_visible;
		
			/** Sets the visibility of a named child widget.
			*/
			virtual void set_visible(const std::string& name, bool value)
			{
				GENERIK_TRACER;
				GENERIK_GDK_ENTER;
				g_object_set(get_widget(name), "visible", value, (char*)0);
			}

			using gtk::widget::get_visible;
		
			/** Gets the visibility of a named child widget.
			*/
			virtual bool get_visible(const std::string& name)
			{
				GENERIK_TRACER;
				GENERIK_GDK_ENTER;
				bool value;
				g_object_get(get_widget(name), "visible", &value, (char*)0);
				return value;
			}
		};
		
	}

}

#endif


